package com.bootdo.common.utils.httpUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import javax.net.ssl.*;
import java.io.*;
import java.net.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

public class HttpUtils {
    //  private static Logger logger = Logger.getLogger(HttpUtils.class);
    public static class TrustAnyTrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }

    public static class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    public int httpPostFile(URL url, File file, int targetID, int sendID, int auditID) throws Exception {
        BufferedReader in = null;
        OutputStream out = null;
        HttpsURLConnection conn = null;
        //HttpURLConnection conn = null;
        String result = "";

        //try {
        //conn = (HttpURLConnection) url.openConnection();

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());

        conn = (HttpsURLConnection) url.openConnection();

        // 发送POST请求必须设置如下两行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);

        //String BOUNDARY = "---------7d4a6d158c9";
        String BOUNDARY = "---------" + targetID + "," + sendID + "," + auditID;

        conn.setSSLSocketFactory(sc.getSocketFactory());
        conn.setHostnameVerifier(new TrustAnyHostnameVerifier());

        conn.setRequestMethod("POST");
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent", "Mozilla/4.0 (Compatible; MSIE 6.0; Windows NT 5.1; SV1)");
        conn.setRequestProperty("Charsert", "UTF-8");
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
        conn.setRequestProperty("sendid", targetID + "");
        conn.connect();

        out = new DataOutputStream(conn.getOutputStream());
        byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();

        StringBuilder sb1 = new StringBuilder();
        sb1.append("--");
        sb1.append(BOUNDARY);
        sb1.append("\r\n");
        sb1.append("Content-Disposition: form-data;name=\"luid\"");
        sb1.append("\r\n");
        sb1.append("\r\n");
        sb1.append("123");
        sb1.append("\r\n");
        out.write(sb1.toString().getBytes());

        StringBuilder sb = new StringBuilder();
        sb.append("--");
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition: form-data;name=\"file\"; filename=\"" + file.getName() + "\"");
        sb.append("\r\n");
        sb.append("Content-Type:application/octet-stream");
        sb.append("\r\n");
        sb.append("\r\n");
        out.write(sb.toString().getBytes());

        DataInputStream in1 = new DataInputStream(new FileInputStream(file));
        int bytes = 0;
        byte[] bufferOut = new byte[1024];
        while ((bytes = in1.read(bufferOut)) != -1) {
            out.write(bufferOut, 0, bytes);
        }
        out.write("\r\n".getBytes());
        in1.close();
        out.write(end_data);

        out.flush();
        in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            result += line;
        }

        /*}
        catch (Exception e)
        {

        }
        finally {
            try
            {
                if (out!=null)
                {
                    out.close();
                }
                if (in!=null)
                {
                    in.close();
                }
            }
            catch (IOException e)
            {

            }
        }*/

        return 1;
    }

    public static String postFile(URL url, File file, JSONArray headers, String username) throws Exception {
        /*
         * 2020/8/4
         * 李国旺
         * 添加logger日志，进行https请求发送文件  请求字符串写入 连接请求成功
         */
        //  logger.error("进行https请求发送文件");
        BufferedReader in = null;
        OutputStream out = null;
        String result = "";

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());

        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

        // 发送POST请求必须设置如下三行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);

        conn.setSSLSocketFactory(sc.getSocketFactory());
        conn.setHostnameVerifier(new TrustAnyHostnameVerifier());

        String BOUNDARY = "---------7d4a6d158c9";

        conn.setRequestMethod("POST");
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent", "Mozilla/4.0 (Compatible; MSIE 6.0; Windows NT 5.1; SV1)");
        conn.setRequestProperty("Charsert", "UTF-8");
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
        conn.setRequestProperty("Cookie", "username=" + username);

        if (headers != null) {
            for (int i = 0; i < headers.size(); i++) {
                JSONObject o = headers.getJSONObject(i);
                String key = o.getString("key");
                String value = o.getString("value");
                conn.setRequestProperty(key, value);
            }
        }

        try {
            conn.connect();

            out = new DataOutputStream(conn.getOutputStream());
            byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();

//            StringBuilder sb1 = new StringBuilder();
//            sb1.append("--");
//            sb1.append(BOUNDARY);
//            sb1.append("\r\n");
//            sb1.append("Content-Disposition: form-data;name=\"luid\"");
//            sb1.append("\r\n");
//            sb1.append("\r\n");
//            sb1.append("123");
//            sb1.append("\r\n");
//            out.write(sb1.toString().getBytes());

            StringBuilder sb = new StringBuilder();
            sb.append("--");
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"file\"; filename=\"" + file.getName() + "\"");
            sb.append("\r\n");
            sb.append("Content-Type:application/octet-stream");
            sb.append("\r\n");
            sb.append("\r\n");
            out.write(sb.toString().getBytes());

            DataInputStream in1 = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in1.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            out.write("\r\n".getBytes());
            in1.close();
            out.write(end_data);

            out.flush();
            //  logger.error(file+ " 请求字符串写入");
            if (conn.getResponseCode() == 200) {
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                //    logger.error(file+ " 连接请求成功");
            }
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        return result;
    }

    public static String postJSON(URL url, String JSON, JSONArray headers, String username) throws Exception {
        BufferedReader in = null;
        OutputStreamWriter out = null;
        StringBuilder result = new StringBuilder();
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//        conn = getConnection(new URL(null,url,new Handler()), METHOD_POST, cty
        // 发送POST请求必须设置如下三行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);

        conn.setSSLSocketFactory(sc.getSocketFactory());
        conn.setHostnameVerifier(new TrustAnyHostnameVerifier());

        conn.setInstanceFollowRedirects(true);
        conn.setRequestMethod("POST"); // 设置请求方式
        conn.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
        conn.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的
        conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");//设置消息头，解决508错误
        conn.setRequestProperty("Cookie", "username=" + username);

        if (headers != null) {
            for (int i = 0; i < headers.size(); i++) {
                JSONObject o = headers.getJSONObject(i);
                String key = o.getString("key");
                String value = o.getString("value");
                conn.setRequestProperty(key, value);
            }
        }

        try {
            // 开始连接请求
            conn.connect();
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // utf-8编码

            // 写入请求的字符串
            out.append(JSON);
            out.flush();
            out.close();

            if (conn.getResponseCode() == 200) {

                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            }
        } catch (Exception e) {
            // System.out.println("发送 POST 请求出现异常！" + e);
            result = new StringBuilder("{\"resCode\":\"1\",\"errCode\":\"1001\",\"resData\":\"\"}");
            e.printStackTrace();

        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }

    public static String postJSONS(URL url, String JSON, JSONArray headers, String username) throws Exception {
        BufferedReader in = null;
        OutputStreamWriter out = null;
        StringBuilder result = new StringBuilder();
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//        conn = getConnection(new URL(null,url,new Handler()), METHOD_POST, cty
        // 发送POST请求必须设置如下三行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);
        conn.setInstanceFollowRedirects(true);
        conn.setRequestMethod("POST"); // 设置请求方式
        conn.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
        conn.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的
        conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");//设置消息头，解决508错误
        conn.setRequestProperty("Cookie", "username=" + username);

        if (headers != null) {
            for (int i = 0; i < headers.size(); i++) {
                JSONObject o = headers.getJSONObject(i);
                String key = o.getString("key");
                String value = o.getString("value");
                conn.setRequestProperty(key, value);
            }
        }

        try {
            // 开始连接请求
            conn.connect();
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // utf-8编码

            // 写入请求的字符串
            out.append(JSON);
            out.flush();
            out.close();

            if (conn.getResponseCode() == 200) {
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            }
        } catch (Exception e) {
            // System.out.println("发送 POST 请求出现异常！" + e);
            result = new StringBuilder("{\"resCode\":\"1\",\"errCode\":\"1001\",\"resData\":\"\"}");
            e.printStackTrace();
            // log.error("远程服务未开启", e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }

    public static String getPostData(InputStream in, int size, String charset) {
        if (in != null && size > 0) {
            byte[] buf = new byte[size];
            try {
                in.read(buf);
                if (charset == null || charset.length() == 0)
                    return new String(buf);
                else {
                    return new String(buf, charset);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static InputStream getInputStream(String URL_PATH) throws IOException {
        InputStream inputStream = null;
        HttpsURLConnection httpurlconn = null;
        try {
            URL url = new URL(URL_PATH);
            if (url != null) {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());


                httpurlconn = (HttpsURLConnection) url.openConnection();
                //设置连接超时时间
                httpurlconn.setConnectTimeout(3000);
                //表示使用GET方式请求
                httpurlconn.setRequestMethod("GET");

                // 发送POST请求必须设置如下两行
                httpurlconn.setDoOutput(true);
                httpurlconn.setDoInput(true);
                httpurlconn.setUseCaches(false);

                httpurlconn.setSSLSocketFactory(sc.getSocketFactory());
                httpurlconn.setHostnameVerifier(new TrustAnyHostnameVerifier());

                int responsecode = httpurlconn.getResponseCode();
                if (responsecode == 200) {
                    //从服务返回一个输入流
                    inputStream = httpurlconn.getInputStream();
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return inputStream;


    }

    public static InputStream getInputStreamP(String URL_PATH) throws IOException {
        InputStream inputStream = null;
        HttpURLConnection httpurlconn = null;
        try {
            URL url = new URL(URL_PATH);
            if (url != null) {

                httpurlconn = (HttpURLConnection) url.openConnection();
                //设置连接超时时间
                httpurlconn.setConnectTimeout(3000);
                //表示使用GET方式请求
                httpurlconn.setRequestMethod("GET");

                // 发送POST请求必须设置如下两行
                httpurlconn.setDoOutput(true);
                httpurlconn.setDoInput(true);
                httpurlconn.setUseCaches(false);
                int responsecode = httpurlconn.getResponseCode();
                if (responsecode == 200) {
                    //从服务返回一个输入流
                    inputStream = httpurlconn.getInputStream();
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return inputStream;


    }

    /**
     * 获取服务器地址
     *
     * @return Ip地址
     */
    public static String getServerIp() {
        // 获取操作系统类型
        String sysType = System.getProperties().getProperty("os.name");
        String ip;
        if (sysType.toLowerCase().startsWith("win")) {  // 如果是Windows系统，获取本地IP地址
            String localIP = null;
            try {
                localIP = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            if (localIP != null) {
                return localIP;
            }
        } else {
            ip = getIpByEthNum("eth0"); // 兼容Linux
            if (ip != null) {
                return ip;
            }
        }
        return "获取服务器IP错误";
    }

    /**
     * 根据网络接口获取IP地址
     *
     * @param ethNum 网络接口名，Linux下是eth0
     * @return
     */
    private static String getIpByEthNum(String ethNum) {
        try {
            Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                if (ethNum.equals(netInterface.getName())) {
                    Enumeration addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        ip = (InetAddress) addresses.nextElement();
                        if (ip != null && ip instanceof Inet4Address) {
                            return ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return "获取服务器IP错误";
    }

    public static boolean telnet(String hostname, int port, int timeout) {
        Socket socket = new Socket();
        boolean isConnected = false;
        try {
            socket.connect(new InetSocketAddress(hostname, port), timeout); // 建立连接
            isConnected = socket.isConnected(); // 通过现有方法查看连通状态
        } catch (IOException e) {
            System.out.println("false");        // 当连不通时，直接抛异常，异常捕获即可
        } finally {
            try {
                socket.close();   // 关闭连接
            } catch (IOException e) {
                System.out.println("false");
            }
        }
        return isConnected;
    }
}
